<template>
  <LoadingBox v-if="showLoading" />
  <ProcessLayout class="wrap" v-if="visible">
    <template #title> {{ t('发起流程') }}【{{ data.item.name }}】 </template>
    <template #close>
      <a-button type="primary" class="clean-icon" @click.stop="$emit('close')">{{
        t('关闭')
      }}</a-button>
    </template>
    <template #left>
      <FlowPanel
        :xml="data.xml"
        :taskRecords="[]"
        :predecessorTasks="selectedPredecessorTasks"
        processId=""
        position="top"
      >
        <FormInformation
          :opinionsComponents="data.opinionsComponents"
          :opinions="data.opinions"
          :disabled="false"
          :formInfos="data.formInfos"
          :formAssignmentData="data.formAssignmentData"
          ref="formInformation"
        />
      </FlowPanel>
    </template>
    <template #right>
      <div class="launch-box">
        <div class="description-box">
          <NodeHead :nodeName="t('发起流程')" class="title" />
          <ProcessInfo class="item-box" :item="data.item" />
        </div>
        <PredecessorTask
          v-if="data.relationTasks && data.relationTasks.length > 0"
          @change="changePredecessorTasks"
          :schemaId="schemaId"
          :relationTasks="data.predecessorTasks"
        />
        <ApproveUser
          v-if="approveUserData.visible"
          :taskList="approveUserData.list"
          :schemaId="approveUserData.schemaId"
          @change="changeApproveUserData"
        />
        <div class="button-box">
          <a-button
            type="primary"
            class="mr-2"
            :disabled="isPublish"
            :loading="data.submitLoading"
            @click="saveLaunch"
            >{{ t('发起') }}</a-button
          >
          <a-button class="mr-2" @click="saveDraft">{{ t('保存草稿') }}</a-button>
        </div>
      </div>
    </template>
  </ProcessLayout>
</template>

<script setup lang="ts">
  import ProcessLayout from './flow/Layout.vue';
  import FlowPanel from './flow/FlowPanel.vue';
  import FormInformation from './flow/FormInformation.vue';
  import { LoadingBox } from '/@/components/ModalPanel/index';
  import ProcessInfo from './flow/ProcessInfo.vue';
  import PredecessorTask from './PredecessorTask.vue';
  import { NodeHead } from '/@/components/ModalPanel/index';
  import ApproveUser from './flow/ApproveUser.vue';
  import { postDraft, putDraft } from '/@/api/workflow/process';
  import {
    postLaunch,
    getStartProcessInfo,
    getReStartProcessInfo,
    reLaunch,
  } from '/@/api/workflow/task';
  import { computed, onMounted, ref, nextTick, toRaw } from 'vue';
  import { ApproveTask, SchemaTaskItem } from '/@/model/workflow/bpmnConfig';
  import userTaskItem from './../hooks/userTaskItem';
  import { separator } from '../../design/bpmn/config/info';
  import { useI18n } from '/@/hooks/web/useI18n';
  const { t } = useI18n();
  const props = defineProps({
    schemaId: {
      type: String,
      required: true,
    },
    draftsJsonStr: {
      type: String,
    },
    draftsId: {
      type: String,
    },
    taskId: {
      type: String,
      required: false,
      default: '',
    },
    processId: {
      type: String,
      required: false,
      default: '',
    },
    formData: {
      type: Object,
    },
    formId: {
      type: String,
    },
  });
  let emits = defineEmits(['close']);
  let formInformation = ref();
  let visible = ref(false);
  let showLoading = ref(false);
  const { data, approveUserData, initProcessData, notificationError, notificationSuccess } =
    userTaskItem();

  const selectedPredecessorTasks = computed(() => {
    return data.predecessorTasks.filter((ele) => {
      return ele.taskId;
    });
  });
  const isPublish = ref(true);

  onMounted(async () => {
    try {
      if (props.processId) {
        // 重新发起
        let res = await getReStartProcessInfo(props.taskId, props.processId);
        res.taskApproveOpinions = [];
        initProcessData(res);
        showLoading.value = false;
      } else if (props.schemaId && props.formId) {
        let res = await getStartProcessInfo(props.schemaId);

        if (props.formData && props.formId) {
          res.formInfos.map((m) => {
            if (m.formConfig.formId === props.formId) {
              m.formData = toRaw(props.formData);
            }
          });
        }
        initProcessData(res);
        showLoading.value = false;
      } else {
        // 发起流程
        let res = await getStartProcessInfo(props.schemaId);
        initProcessData(res);
        showLoading.value = false;
      }
    } catch (error) {
      showLoading.value = false;
    }

    showLoading.value = false;
    visible.value = true;

    initDraftsFormData();
  });
  async function initDraftsFormData() {
    await nextTick();

    let models = await formInformation.value.getFormModels();
    isPublish.value = Object.keys(models).length > 0 ? false : true;
    if (props.draftsJsonStr) {
      let formDataJson = JSON.parse(props.draftsJsonStr);
      let formData: Array<any> = [];

      data.formInfos.forEach((item) => {
        if (
          formDataJson &&
          item.formConfig &&
          item.formConfig.key &&
          formDataJson[item.formConfig.key]
        ) {
          formData.push(item.formConfig.key ? formDataJson[item.formConfig.key] : {});
        }
      });
      await formInformation.value.setFormData(formData);
    }
  }
  function getUploadFileFolderIds(formModels) {
    let fileFolderIds: Array<string> = [];
    let uploadComponentIds = formInformation.value.getUploadComponentIds();
    uploadComponentIds.forEach((ids) => {
      if (ids.includes(separator)) {
        let arr = ids.split(separator);
        if (arr.length == 2 && formModels[arr[0]][arr[1]]) {
          fileFolderIds.push(formModels[arr[0]][arr[1]]);
        } else if (
          arr.length == 3 &&
          formModels[arr[0]][arr[1]] &&
          Array.isArray(formModels[arr[0]][arr[1]])
        ) {
          formModels[arr[0]][arr[1]].forEach((o) => {
            fileFolderIds.push(o[arr[2]]);
          });
        }
      }
    });
    return fileFolderIds;
  }
  async function saveLaunch() {
    data.submitLoading = true;
    try {
      let validateForms = await formInformation.value.validateForm();
      if (validateForms.length > 0) {
        let successValidate = validateForms.filter((ele) => {
          return ele.validate;
        });
        if (successValidate.length == validateForms.length) {
          let formModels = await formInformation.value.getFormModels();
          let relationTasks: Array<{
            schemaId: string;
            taskId: string;
          }> = [];
          if (data.predecessorTasks && data.predecessorTasks.length > 0) {
            relationTasks = data.predecessorTasks.map((ele) => {
              return { taskId: ele.taskId, schemaId: ele.schemaId };
            });
          }
          let fileFolderIds: Array<string> = getUploadFileFolderIds(formModels);
          //如果传入了processId  代表是重新发起流程
          let res;
          if (props.processId) {
            res = await reLaunch(
              props.processId,
              props.schemaId,
              formModels,
              relationTasks,
              fileFolderIds,
            );
          } else {
            res = await postLaunch(props.schemaId, formModels, relationTasks, fileFolderIds);
          }

          // 下一节点审批人
          let taskList: Array<ApproveTask> = [];
          if (res && res.length > 0) {
            taskList = res
              .filter((ele) => {
                return ele.isMultiInstance == false && ele.isAppoint == true;
              })
              .map((ele) => {
                return {
                  taskId: ele.taskId,
                  taskName: ele.taskName,
                  provisionalApprover: ele.provisionalApprover,
                  selectIds: [],
                };
              });
            if (taskList.length > 0) {
              approveUserData.list = taskList;
              approveUserData.schemaId = props.schemaId;
              approveUserData.visible = true;
              data.submitLoading = false;
            } else {
              data.submitLoading = false;
              save(true, t('发起流程'));
            }
          } else {
            data.submitLoading = false;
            save(true, t('发起流程'));
          }
        } else {
          data.submitLoading = false;
          notificationError(t('发起流程'), t('表单校验未通过'));
        }
      }
    } catch (error) {
      data.submitLoading = false;
      notificationError(t('发起流程'), t('发起流程失败'));
    }
  }

  async function saveDraft() {
    try {
      let formModels = await formInformation.value.getFormModels();
      if (props.draftsId) {
        let res = await putDraft(props.schemaId, formModels, props.draftsId);
        save(res, t('保存草稿'));
      } else {
        let res = await postDraft(props.schemaId, formModels);
        save(res, t('保存草稿'));
      }
    } catch (error) {
      notificationError(t('保存草稿'));
    }
  }
  function changePredecessorTasks(list: Array<SchemaTaskItem>) {
    data.predecessorTasks = list;
  }
  function save(res: boolean, title: string) {
    if (res) {
      notificationSuccess(title);
      emits('close');
    } else {
      notificationError(title);
    }
  }

  function changeApproveUserData() {
    approveUserData.visible = false;
    emits('close');
  }
</script>
<style lang="less" scoped>
  .description-box {
    display: flex;
    flex-direction: column;
    padding-top: 10px;
    align-items: center;
    justify-content: center;
    color: rgb(102 102 102 / 99.6%);
    margin-bottom: 20px;

    .title {
      align-self: flex-start;
      margin-bottom: 20px;
    }

    .item-box {
      align-self: flex-start;
    }
  }
</style>
